/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef OLA_LOG_H
#define OLA_LOG_H

#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

#define OLA_LOG_INER_LEVEL_MIN      0
#define OLA_LOG_INER_LEVEL_EMERG    1
#define OLA_LOG_INER_LEVEL_ALERT    2
#define OLA_LOG_INER_LEVEL_CRIT     3
#define OLA_LOG_INER_LEVEL_ERROR    4
#define OLA_LOG_INER_LEVEL_WARNING  5
#define OLA_LOG_INER_LEVEL_NOTICE   6
#define OLA_LOG_INER_LEVEL_INFO     7
#define OLA_LOG_INER_LEVEL_DEBUG    8

#ifndef OLA_LOG_BUILD_LEVEL
#define OLA_LOG_BUILD_LEVEL OLA_LOG_INER_LEVEL_DEBUG
#endif

#ifndef OLA_LOG_DEFAULT_LEVEL
#define OLA_LOG_DEFAULT_LEVEL OLA_LOG_BUILD_LEVEL
#endif

int OlaPrintf(const char *format, ...);

bool OlaIsLogLevelPrint(int level);

int OlaSetLogLevel(int level);

int OlaGetLogLevel(void);

int OlaLogLevelReset(void);

void OlaDumpChar(const char *str, unsigned int len);

void OlaDumpHex(const unsigned char *data, unsigned int len);

#if (OLA_LOG_BUILD_LEVEL >= OLA_LOG_INER_LEVEL_EMERG)
#define OlaLogEmerg(...) \
    do { \
        if (OlaIsLogLevelPrint(OLA_LOG_INER_LEVEL_EMERG)) { \
            OlaPrintf("OLA_EMG:%s() %d,", __func__, __LINE__); \
            OlaPrintf(__VA_ARGS__); \
            OlaPrintf("\r\n"); \
        } \
    } while (0)
#else
#define OlaLogEmerg(...)
#endif

#if (OLA_LOG_BUILD_LEVEL >= OLA_LOG_INER_LEVEL_ALERT)
#define OlaLogAlert(...) \
    do { \
        if (OlaIsLogLevelPrint(OLA_LOG_INER_LEVEL_ALERT)) { \
            OlaPrintf("OLA_ALT:%s() %d,", __func__, __LINE__); \
            OlaPrintf(__VA_ARGS__); \
            OlaPrintf("\r\n"); \
        } \
    } while (0)
#else
#define OlaLogAlert(...)
#endif

#if (OLA_LOG_BUILD_LEVEL >= OLA_LOG_INER_LEVEL_CRIT)
#define OlaLogCrit(...) \
    do { \
        if (OlaIsLogLevelPrint(OLA_LOG_INER_LEVEL_CRIT)) { \
            OlaPrintf("OLA_CRT:%s() %d,", __func__, __LINE__); \
            OlaPrintf(__VA_ARGS__); \
            OlaPrintf("\r\n"); \
        } \
    } while (0)
#else
#define OlaLogCrit(...)
#endif

#if (OLA_LOG_BUILD_LEVEL >= OLA_LOG_INER_LEVEL_ERROR)
#define OlaLogError(...) \
    do { \
        if (OlaIsLogLevelPrint(OLA_LOG_INER_LEVEL_ERROR)) { \
            OlaPrintf("OLA_ERR:%s() %d,", __func__, __LINE__); \
            OlaPrintf(__VA_ARGS__); \
            OlaPrintf("\r\n"); \
        } \
    } while (0)
#else
#define OlaLogError(...)
#endif

#if (OLA_LOG_BUILD_LEVEL >= OLA_LOG_INER_LEVEL_WARNING)
#define OlaLogWarning(...) \
    do { \
        if (OlaIsLogLevelPrint(OLA_LOG_INER_LEVEL_WARNING)) { \
            OlaPrintf("OLA_WRN:%s() %d,", __func__, __LINE__); \
            OlaPrintf(__VA_ARGS__); \
            OlaPrintf("\r\n"); \
        } \
    } while (0)
#else
#define OlaLogWarning(...)
#endif

#if (OLA_LOG_BUILD_LEVEL >= OLA_LOG_INER_LEVEL_NOTICE)
#define OlaLogNotice(...) \
    do { \
        if (OlaIsLogLevelPrint(OLA_LOG_INER_LEVEL_NOTICE)) { \
            OlaPrintf("OLA_NTC:%s() %d,", __func__, __LINE__); \
            OlaPrintf(__VA_ARGS__); \
            OlaPrintf("\r\n"); \
        } \
    } while (0)
#else
#define OlaLogNotice(...)
#endif

#if (OLA_LOG_BUILD_LEVEL >= OLA_LOG_INER_LEVEL_INFO)
#define OlaLogInfo(...) \
    do { \
        if (OlaIsLogLevelPrint(OLA_LOG_INER_LEVEL_INFO)) { \
            OlaPrintf("OLA_INF:%s() %d,", __func__, __LINE__); \
            OlaPrintf(__VA_ARGS__); \
            OlaPrintf("\r\n"); \
        } \
    } while (0)
#else
#define OlaLogInfo(...)
#endif

#if (OLA_LOG_BUILD_LEVEL >= OLA_LOG_INER_LEVEL_DEBUG)
#define OlaLogDebug(...) \
    do { \
        if (OlaIsLogLevelPrint(OLA_LOG_INER_LEVEL_DEBUG)) { \
            OlaPrintf("OLA_DBG:%s() %d,", __func__, __LINE__); \
            OlaPrintf(__VA_ARGS__); \
            OlaPrintf("\r\n"); \
        } \
    } while (0)
#else
#define OlaLogDebug(...)
#endif

#ifdef __cplusplus
}
#endif

#endif /* OLA_LOG_H */
